package common.element;

import common.exception.CommonErrorCode;
import common.exception.DataExchangeException;

import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * 越界检测
 */
public final class OverFlowChecker
{
    public static final BigInteger max_long_value = BigInteger.valueOf(Long.MAX_VALUE);

    public static final BigInteger min_long_value = BigInteger.valueOf(Long.MIN_VALUE);

    public static final BigDecimal min_double_value = new BigDecimal(String.valueOf(Double.MIN_VALUE));

    public static final BigDecimal max_double_value = new BigDecimal(String.valueOf(Double.MAX_VALUE));
    //


    public static void validateDataIsNotOverFlowLongRange(final BigInteger bigInteger)
    {
        boolean isOverFlow = OverFlowChecker.isOverFlowLongRange(bigInteger);

        if (isOverFlow)
        {
            throw DataExchangeException.asDataExchangeException(
                    CommonErrorCode.CONVERT_OVER_FLOW,
                    String.format("[%s] 转为Long类型出现溢出 .", bigInteger.toString()));
        }
    }

    public static boolean isOverFlowLongRange(final BigInteger bigInteger)
    {
        return (bigInteger.compareTo(OverFlowChecker.max_long_value) > 0 || bigInteger
                .compareTo(OverFlowChecker.min_long_value) < 0);

    }
    //


    public static void validateDataIsNotOverFlowDoubleRange(final BigDecimal bigDecimal)
    {
        boolean isOverFlow = OverFlowChecker.isOverFlowDoubleRange(bigDecimal);
        if (isOverFlow)
        {
            throw DataExchangeException.asDataExchangeException(
                    CommonErrorCode.CONVERT_OVER_FLOW,
                    String.format("[%s]转为Double类型出现溢出 .",
                            bigDecimal.toPlainString()));
        }
    }

    public static boolean isOverFlowDoubleRange(final BigDecimal bigDecimal)
    {
        if (bigDecimal.signum() == 0)
        {
            return false;
        }

        BigDecimal newBigDecimal = bigDecimal;
        boolean isPositive = bigDecimal.signum() == 1;
        if (!isPositive)
        {
            newBigDecimal = bigDecimal.negate();
        }

        return (newBigDecimal.compareTo(min_double_value) < 0 || newBigDecimal
                .compareTo(max_double_value) > 0);
    }
}
